package com.pajk.user.api;

/**
* 登录注册接口
*
* @author haomin
*/
import com.pajk.user.exception.UserServiceHttpCode;
import com.pajk.user.model.LoginResp;
import com.pajk.user.model.RegisterResp;
import com.pajk.user.model.SafetyQuestions;
import com.pajk.user.model.UpstreamSmsInfo;

import net.pocrd.annotation.*;
import net.pocrd.define.CommonParameter;
import net.pocrd.define.SecurityType;

@ApiGroup(name="user", minCode = 1000000, maxCode = 2000000, codeDefine = UserServiceHttpCode.class)
public interface LoginServiceHttpExport {

    /**
     * 用户静态密码登录
     *
     * @param mobile 电话号码
     * @param password 用户静态密码（MD5加密）
     * @return 用户登录态Token
     */
    // TODO general return code
    @HttpApi(name="user.login", desc="用户静态密码登录", security = SecurityType.RegisteredDevice)
    @DesignedErrorCode({UserServiceHttpCode.C_USERNAME_OR_PASSWORD_ERROR, UserServiceHttpCode.C_LOGIN_FAILED, UserServiceHttpCode.C_USER_NOT_FOUND})
    LoginResp login(@ApiParameter(required = true, name = "mobile", desc = "用户手机号，格式参考：13926583227")String mobile,
    				@ApiAutowired(CommonParameter.deviceToken) String deviceToken,
                    @ApiParameter(required = true, rsaEncrypted = true, name = "password", desc = "静态密码 md5(pass+salt(\"pajk.cn\"))")String password);

    /**
     * 登录注销
     *
     * @param userId 用户名
     * @param deviceId 设备号
     * @return logout是否成功
     */
    @HttpApi(name="user.logout", desc="登录注销", security = SecurityType.UserLogin)
    @DesignedErrorCode(UserServiceHttpCode.C_STATIC_PASSWORD_NOT_SET)
    boolean logout(@ApiAutowired(CommonParameter.userId) long userId,
                   @ApiAutowired(CommonParameter.deviceId) long deviceId);

    /**
     * 更新用户token
     *
     * @param expiredToken 已经过期的用户token
     * @return 新的userToken
     */
    @HttpApi(name = "user.renewUserToken", desc = "更新用户Token", security = SecurityType.RegisteredDevice)
    LoginResp renewUserToken(@ApiAutowired(CommonParameter.token) String expiredToken,
                             @ApiAutowired(CommonParameter.applicationId) int appId);

    /**
     * 重置用户静态密码
     *
     * @param mobile 需要重置密码的用户手机号
     * @param newPass 要重置的密码
     * @return 重置是否成功
     */
    @HttpApi(name="user.resetPassword", desc="重置用户静态密码", security = SecurityType.MobileOwnerTrustedDevice)
    boolean resetPassword(@ApiAutowired(CommonParameter.phoneNumber) long mobile,
                          @ApiParameter(required = true, rsaEncrypted = true, name = "newPass", desc = "新密码, md5(pass+salt(\"pajk.cn\"))") String newPass);

    /**
     * 设置用户密码
     *
     * @param userId 需要修改密码的用户ID
     * @param newPass 新密码
     * @return 是否成功
     */
    @HttpApi(name="user.changePassword", desc="在登录态设置用户密码", security = SecurityType.UserLogin)
    @DesignedErrorCode({UserServiceHttpCode.C_SAME_PASSWORD_ERROR})
    boolean changePassword(@ApiAutowired(CommonParameter.userId) long userId,
                           @ApiParameter(required = true, rsaEncrypted = true, name = "newPass", desc = "新密码, md5(pass+salt(\"pajk.cn\"))") String newPass);

    /**
     * 绑定手机号
     *
     * @param mobile 要绑定的手机号
     * @return 是否成功
     */
    @HttpApi(name="user.bindMobile", desc="在登录态设置用户密码", security = SecurityType.UserLogin)
    boolean bindMobile(@ApiAutowired(CommonParameter.userId) long userId,@ApiParameter(required = true, name = "mobile", desc = "用户手机号，格式参考：13926583227")String mobile);

    /**
     * 使用手机号注册用户
     *
     *
     * @param mobile 用户手机号
     * @return 注册是否成功
     */
    @HttpApi(name = "user.register", desc="使用手机号注册", security = SecurityType.MobileOwner)
    @DesignedErrorCode({UserServiceHttpCode.C_USER_EXIST})
    RegisterResp register(
    		@ApiAutowired(CommonParameter.phoneNumber) String mobile,
    		@ApiAutowired(CommonParameter.deviceToken) String dtk,
            @ApiParameter(required = true, name = "force", desc = "针对手机号已经注册的情况, false会返回错; true会强制注册, 并将改手机号从原用户上擦除, 绑定到新创建的用户档案上") boolean force);

    /**
     * 第三方用户登录
     *
     * @param type 第三方类型
     * @param code 第三方授权码
     * @return 用户登录Token
     */
    @HttpApi(name = "user.faderatedLogin", desc = "第三方用户登录", security = SecurityType.None)
    @DesignedErrorCode({UserServiceHttpCode.C_LOGIN_FAILED})
    LoginResp federateLogin(@ApiParameter(required = true, name = "type", desc = "第三方类型，目前支持：\'WEIXIN\' ") String type,
                            @ApiParameter(required = false, name = "code", desc = "第三方授权码") String code,
                            @ApiAutowired(CommonParameter.applicationId) int appId);

    /**
     * 请求服务端发送动态短信验证码
     *
     * @param mobile 要发送动态验证码的手机号
     * @param scenario 发送场景，分为“LOGIN”和“REGISTER”
     * @return 发送上行短信所需信息
     */
    @HttpApi(name = "user.requestSmsPassoword", desc = "发送动态验证密码", security = SecurityType.RegisteredDevice)
    @DesignedErrorCode({UserServiceHttpCode.C_UNSUPPORTED_PHONE_NUM})
    UpstreamSmsInfo requestSmsPassword(@ApiParameter(required = true, name = "mobile", desc = "用户手机号，格式参考：13926583227")String mobile,
                                       @ApiParameter(required = true, name = "scenario", desc = "请求动态密码的场景，可选参数\"LOGIN\"、\"REGISTER\"。" +
                                        "对于前者，手机号必须已注册(可能返回:USER_NOT_FOUND)，对于后者，手机号必须未注册(可能返回:USER_EXIST)")String scenario);

    /**
     * 使用短信动态密码登录
     *
     * @param smsPass 短信动态密码
     * @return 用户登录Token
     */
    @HttpApi(name = "user.smsPasswordLogin", desc = "短信动态密码登录", security = SecurityType.MobileOwnerTrustedDevice)
    @DesignedErrorCode({UserServiceHttpCode.C_SMS_PASSWORD_ERROR})
    LoginResp smsPasswordLogin(@ApiAutowired(CommonParameter.phoneNumber) String mobile,
                               @ApiAutowired(CommonParameter.deviceToken) String deviceToken,
                               @ApiAutowired(CommonParameter.dynamic)String smsPass);


    /**
     * 为获取受信设备请求安全问题
     *
     * @param mobile 用户主键
     * @param deviceId 待受信设备号
     * @return 安全问题对象，包括所有题目。
     *
     */
    @HttpApi(name = "user.requestSafetyQuestionsForTrustDevice", desc = "为获取受信设备请求安全问题", security = SecurityType.MobileOwner)
    //@DesignedErrorCode({ReturnCode._C_ACCESS_DENIED})
    SafetyQuestions requestSafetyQuestionsForTrustDevice(@ApiAutowired(CommonParameter.phoneNumber)String mobile,
                                                         @ApiAutowired(CommonParameter.deviceId) long deviceId);


    /**
     * 为获取受信设备做安全问题批改
     *
     * @param mobile        待授予受信设备的用户的手机号
     * @param deviceId      待受信设备号
     * @param appId         应用号
     * @param safetyAnswers 安全问题答案
     * @return 是否成功
     *
     * 关键逻辑：
     * 1. 验证QuestionUID是否合法
     * 2. 验证问题答案
     * 3. 添加设备受信
     *
     */
    @HttpApi(name = "user.gradeSafetyAnswersForTrustDevice", desc = "为获取受信设备做安全问题批改", security = SecurityType.MobileOwner)
    @DesignedErrorCode({UserServiceHttpCode.C_SAFETYEXAM_NOT_QUALIFIED})
    boolean gradeSafetyAnswersForTrustDevice(@ApiAutowired(CommonParameter.phoneNumber) String mobile,
                                             @ApiAutowired(CommonParameter.deviceId) long deviceId,
                                             @ApiAutowired(CommonParameter.applicationId) int appId,
                                             @ApiParameter(required = true, name = "safetyAnswers", desc = "安全问题答案,json format: {\"answers\":[{\"result\":[\"1970-01-01\"],\"templeteId\":1},{\"result\":[\"frank\"],\"templeteId\":3},{\"result\":[\"170\"],\"templeteId\":5}],\"questionUID\":\"75874c7f478234351bd2d6c78428ac9e\"}")
                                             String safetyAnswers);

    /**
     * 为获取用户所有权请求安全问题
     *
     * @param targetUserId
     * @return
     */
    @HttpApi(name = "user.requestSafetyQuestionsForUserAquire", desc = "为获取用户所有权请求安全问题", security = SecurityType.UserLogin)
    @DesignedErrorCode({UserServiceHttpCode.C_USER_NOT_AQUIRABLE})
    SafetyQuestions requestSafetyQuestionsForUserAquire(@ApiParameter(required = true, name = "targetUserId", desc = "目标用户ID") long targetUserId);


    /**
     * 为获取用户所有权做安全问题批改
     *
     *
     * @param targetUserId 待获取用户主键
     * @param safetyAnswers 安全问题答案
     * @return 是否成功
     *
     * 关键逻辑：
     * 1. 验证QuestionUID是否合法
     * 2. 验证安全问题答案是否正确
     * 3. replace用户
     */
    @HttpApi(name = "user.aquireUserBySafetyAnswer", desc = "通过回答安全问题获取用户所有权", security = SecurityType.UserLogin)
    @DesignedErrorCode({UserServiceHttpCode.C_SAFETYEXAM_NOT_QUALIFIED})
    boolean aquireUserBySafetyAnswer(@ApiAutowired(CommonParameter.userId) long loginUserId,
                                     @ApiParameter(required = true, name = "targetUserId", desc = "待获取用户主键") long targetUserId,
                                     @ApiParameter(required = true, name = "safetyAnswers", desc = "安全问题答案,json format: {\"answers\":[{\"result\":[\"1970-01-01\"],\"templeteId\":1},{\"result\":[\"frank\"],\"templeteId\":3},{\"result\":[\"170\"],\"templeteId\":5}],\"questionUID\":\"75874c7f478234351bd2d6c78428ac9e\"}") 
    												String safetyAnswers);
}
